/**
 * @param {string} s1
 * @param {string} s2
 * @return {boolean}
 */
var checkInclusion = function (s1, s2) {
    let len1 = s1.length
    let len2 = s2.length
    let arr = new Array(26).fill(0)
    let diff = 0
    for (let i = 0; i < len1; i++) {

        // s1,s2的--和 ++  ,可以想像成，s1向左偏移，s2中的元素则向右偏移，当所有元素都不偏不倚在0的位置，就说明存在相同的子串。
        --arr[s1.charCodeAt(i) - 'a'.charCodeAt()]
        ++arr[s2.charCodeAt(i) - 'a'.charCodeAt()]
    }

    // 统计diff
    for (let i = 0; i < arr.length; i++) {

        // 注意，非零的才统计，并且每个字符有差异为1，无差异为0
        if (arr[i]) {
            diff++
        }
    }


    // 如果开始没有差异，则返回
    if (diff === 0) {
        return true
    }

    // 移动窗口
    let i = len1
    for (; i < len2; i++) {

        // 窗口左边元素出，右边元素进
        // 如果将要进入的元素和将要出去的元素一样，没啥差异，那么此次就跳过
        if (s2[i] === s2[i - len1]) {
            continue
        }

        // 如果不一样，下面的每涉及到更新arr数组时，都要去判断是否需要更新diff值
        // 1. 先开始操作右边元素进入窗口
        // 右边元素进入之前，当前字符对应个数为0，意味是从 【0 ->非0】，则diff要加一
        if (arr[s2.charCodeAt(i) - 'a'.charCodeAt()] === 0) {
            diff++
        }

        // 右边元素进入窗口，更新差异统计值。！！因为是对s2进行滑动窗口操作，加入s2的元素就意味着向右偏移，因此是++
        ++arr[s2.charCodeAt(i) - 'a'.charCodeAt()]

        // 右边元素进入窗口之后，此时如果该元素对应的统计值为0，则表示为【非0 -> 0】, 则diff要减一
        if (arr[s2.charCodeAt(i) - 'a'.charCodeAt()] === 0) {
            diff--
        }

        // 2. 操作左边元素移出窗口，同样的操作
        // 左边元素移出之前，当前字符对应个数为0，意味着是从 【0 -> 非0】，则diff要加一
        if (arr[s2.charCodeAt(i - len1) - 'a'.charCodeAt()] === 0) {

            diff++
        }

        // 进行移出，更新差异统计值。！！因为是对s2进行滑动窗口操作，移除s2的元素就意味着要还原之前的右移，因此是--
        --arr[s2.charCodeAt(i - len1) - 'a'.charCodeAt()]

        // 左边元素移出之后，此时如果该元素对应的统计值为0，则表示为【非0 -> 0】, 则diff要减一
        if (arr[s2.charCodeAt(i - len1) - 'a'.charCodeAt()] === 0) {
            diff--
        }
        // 此时窗口一次移动完成，看是否满足条件，满足条件则退出
        if (diff === 0) {
            return true
        }
    }
    return false
};
console.log(checkInclusion("ab", "eidbaooo"))

//================v2要点总结===============
/**
 * 1. 对 v1的优化
 * 2. 优化1：首先数组长度进行削减，声明只有小写字母，那总长度就只有26
 * 3. 优化2： 只统计差异性，即题解1的优化版本
 * 4. 注意思考什么情况下进行--或++
 * 5. 注意数组的下标，不能超过26，意味着所有的字母的ASCII码都要减去 a 的ASCII码
 */